#ifndef SHAREDPOINTER_H
#define SHAREDPOINTER_H

#include <stddef.h>
#include <assert.h>
#include <stdio.h>

template <class T>
class SharedPointer {
  private:
    T* pointer;
    size_t* counter;  // shared counter

    void free() {
      if(--*counter == 0)
      {
        delete pointer;
        delete counter;
      }
    };

    void copy(const SharedPointer<T>& src) {
        pointer = src.pointer;
        counter = src.counter;
        ++*counter;
    };
  public:
    SharedPointer(): pointer(new T()), counter(new size_t(1)) {
    };
    SharedPointer(T* p): pointer(p), counter(new size_t(1)) {
    };
    SharedPointer(const SharedPointer<T>& src) {
      copy(src);
    };

    ~SharedPointer() {
      free();
    };

    T& operator*() {
      return *pointer;
    };

    T* operator->() {
      return pointer;
    };

    SharedPointer<T>& operator=(const SharedPointer<T>& src) {
      if (this != &src) {  // self assignment fix
        free();
        copy(src);
      }
      return *this;
    };

    bool operator==(const SharedPointer<T>& src) {
      return pointer == src.pointer;
    }

    operator bool() const {
      return pointer != 0;
    };
};

#endif
